package com.rockcent.service;

import com.rockcent.helper.CustomerFundFlowHelper;
import com.rockcent.mall.lib.helper.MallFundFlowHelper;
import com.rockcent.common.common.BusinessException;
import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.*;
import com.rockcent.mall.lib.dto.CustomerDto;
import com.rockcent.mall.lib.helper.OrderEventHelper;
import com.rockcent.mall.lib.helper.OrderStatusHelper;
import com.rockcent.mall.lib.repository.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * Created by oyhk on 2016/11/25.
 * <p>
 * 订单service
 * <p>
 * 这个service 到时候做成动态开启，目前直接开启
 */
@Service
public class OrderService {

    private final Logger log = LoggerFactory.getLogger(OrderService.class);
    @Autowired
    private MallOrderRepository mallOrderRepository;
    @Autowired
    private MallOrderPaymentRepository mallOrderPaymentRepository;
    @Autowired
    private MerchantOrderRepository merchantOrderRepository;
    @Autowired
    private MallFundRepository mallFundRepository;
    @Autowired
    private MallFundFlowRepository mallFundFlowRepository;
    @Autowired
    private CustomerFundRepository customerFundRepository;
    @Autowired
    private CustomerFundFlowRepository customerFundFlowRepository;
    @Autowired
    private MerchantOrderItemRepository merchantOrderItemRepository;
    @Autowired
    private ProductQuantityRepository productQuantityRepository;
    @Autowired
    private MerchantProductRepository merchantProductRepository;
    @Autowired
    private OrderEventHelper orderEventHelper;
    @Autowired
    private MallCashCouponSrv mallCashCouponSrv;

    /**
     * 订单取消
     *
     * @param customerDto  用户信息
     * @param mallOrderNum 平台订单号
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void cancel(CustomerDto customerDto, String mallOrderNum) {
        if (customerDto == null) {
            throw new BusinessException("用户信息不能为空", log);
        }
        Long customerDtoId = customerDto.getId();
        MallOrder mallOrder = mallOrderRepository.findByOrderNumAndMallIdAndCustomerId(mallOrderNum, customerDto.getMallId(), customerDtoId);
        if (mallOrder == null) {
            throw new BusinessException(MallOrder.CLASS_TITLE + MallOrder.REMIND_RECORD_IS_NOT_EXIST, log);
        }
        if (mallOrder.getStatus() == MallOrderStatus.PAYED) {
            throw new BusinessException("已支付订单不能取消", log);
        }
        String orderNum = mallOrder.getOrderNum();
        Long mallId = mallOrder.getMallId();

        List<MerchantOrder> merchantOrderList = merchantOrderRepository.findByMallOrderNum(orderNum);
        if (merchantOrderList.size() == 0) {
            throw new BusinessException(String.format("平台订单异常，不能取消订单。mall_order_num : %s", orderNum), log);
        }

        boolean isWaitPayingCancel = false;
        boolean isPayedCancel = false;

        if (mallOrder.getStatus() == MallOrderStatus.WAIT_PAYING) {
            // 没有支付 取消订单
            isWaitPayingCancel = merchantOrderList.stream().allMatch(merchantOrder -> merchantOrder.getStatus() == OrderStatus.WAIT_PAYING);

            //还原现金券和积分卡券
            mallCashCouponSrv.refundIntegrationCoupon(mallOrder, false);

        } else if (mallOrder.getStatus() == MallOrderStatus.PAYED) {
//            MallOrderPayment mallOrderPayment = mallOrderPaymentRepository.findByMallOrderNumAndMallId(orderNum, mallId);
//            if (mallOrderPayment == null) {
//                throw new BusinessException(MallOrderPayment.CLASS_TITLE + MallOrderPayment.REMIND_RECORD_IS_NOT_EXIST, log);
//            }
//            isPayedCancel = merchantOrderList.stream()
//                    .allMatch(merchantOrder ->
//                            (merchantOrder.getOrderType() == OrderType.GOODS
//                                    && (merchantOrder.getStatus() == OrderStatus.WAIT_STOCK
//                                    || merchantOrder.getStatus() == OrderStatus.WAIT_SHIPPED))
//                                    || (merchantOrder.getOrderType() == OrderType.SERVICE && merchantOrder.getRefundable() == Whether.YES));
//            // 当支付后 取消订单，把客户下单资金退回
//            if (isPayedCancel) {
//                BigDecimal amount = mallOrderPayment.getAmount();
//                refund(customerDtoId, orderNum, null, mallId, amount);
//            }
        }


        if (isWaitPayingCancel || isPayedCancel) {
            OrderStatusHelper.SINGLETON.mallOrderCancel(mallOrder, merchantOrderList);
            mallOrderRepository.save(mallOrder);
            merchantOrderRepository.save(merchantOrderList);
            merchantOrderList.forEach(merchantOrder -> {
                orderEventHelper.saveOrderEvent(merchantOrder, OrderEventType.CANCEL, mallOrder.getCustomerName(), mallOrder.getCustomerId());
            });
        }
        // 库存还原
        merchantOrderList.forEach(merchantOrder -> {
            List<MerchantOrderItem> merchantOrderItemList = merchantOrderItemRepository.findByMerchantOrderIdAndMerchantId(merchantOrder.getId(), merchantOrder.getMerchantId());
            merchantOrderItemList.forEach(merchantOrderItem -> {
                Product product = merchantProductRepository.findByIdAndIsDelete(merchantOrderItem.getProductId(), Whether.NO);
                if (product != null) {
                    ProductQuantity productQuantity = productQuantityRepository.findOne(product.getProductQuantityId());
                    productQuantity.setFrozenQuantity(productQuantity.getFrozenQuantity() - merchantOrderItem.getBuyCount());
                    productQuantity.setQuantity(productQuantity.getQuantity() + merchantOrderItem.getBuyCount());
                    productQuantityRepository.save(productQuantity);
                }
            });
        });

    }

    /**
     * 资金原路返回
     *
     * @param customerDtoId    用户id
     * @param mallOrderNum     平台订单号
     * @param merchantOrderNum 商家订单号
     * @param mallId           平台id
     * @param amount           退回金额
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void refund(Long customerDtoId, String mallOrderNum, String merchantOrderNum, Long mallId, BigDecimal amount) {
        MallFund mallFund = mallFundRepository.findByMallId(mallId);
        if (null != mallFund) {
            mallFund = mallFundRepository.findOne(mallFund.getId());
            log.info("======================>mallFund1:" + mallFund);
            MallFundFlow mallFundFlow = MallFundFlowHelper.SINGLEONE.create(mallFund, mallOrderNum, BigDecimal.ZERO, amount, amount, FundTransactionFlow.EXPEND, MallFundFlowTransactionType.F_ORDER_CANCEL_EXPEND, null, merchantOrderNum);
            log.info("======================>mallFundFlow:{}", mallFundFlow);
            mallFund.setFrozen(mallFundFlow.getFrozen());
            mallFund.setTotalAmount(mallFundFlow.getTotalAmount());
            mallFundFlowRepository.save(mallFundFlow);


            CustomerFund customerFund = customerFundRepository.findByCustomerIdAndIsDelete(customerDtoId, Whether.NO);
            if (null == customerFund) {
                log.error("======================>customerId:{}的用户资金表不存在", customerDtoId);
                return;
            }

            log.info("======================>customerFund:{}", customerFund);

            CustomerFundFlow customerFundFlow = CustomerFundFlowHelper.SINGLE.create(customerFund, mallId, mallOrderNum, amount, BigDecimal.ZERO, amount, FundTransactionFlow.INCOME, CustomerFundFlowTransactionType.A_ORDER_CANCEL);
            log.info("======================>customerFundFlow:{}", customerFundFlow);

            //        customerFund.setFrozen(customerFundFlow.getFrozen());
            customerFund.setTotalAmount(customerFundFlow.getTotalAmount());
            customerFund.setAvailableAmount(customerFundFlow.getAvailableAmount());
            customerFundFlowRepository.save(customerFundFlow);
            mallFund = mallFundRepository.findOne(mallFund.getId());
            log.info("======================>mallFund:{}", mallFund);

        } else {
            log.error("======================>mallId:{}的平台资金表不存在", customerDtoId);
        }

    }


}
